<template>
  <el-dialog
    :model-value="visible"
    :title="$t('pictureManager.uploadPic')"
    top="200px"
    width="770px"
    class="component-upload-pic"
    @close="handleDialogClose"
  >
    <div class="elx-imgbox-dialog">
      <div class="elx-main">
        <!-- native modifier has been removed, please confirm whether the function has been affected  -->
        <el-form
          label-width="auto"
          @submit.prevent
        >
          <el-form-item :label="$t('resource.selectGroup')+':'">
            <el-select
              v-model="selectGroup"

              clearable
              :placeholder="$t('tip.select')"
              class="select-group-box-item"
            >
              <el-option
                v-for="item in groupList"
                :key="item.attachFileGroupId"
                :label="item.name"
                :value="item.attachFileGroupId"
              />
            </el-select>
            <div
              class="default-btn text-btn select-group-box-item"
              @click="createGroup"
            >
              {{ $t("resource.newGroup") }}
            </div>
          </el-form-item>
          <el-form-item :label="$t('pictureManager.uploadPic')+':'">
            <el-upload
              ref="uploadRef"
              v-model:file-list="fileList"
              :class="['upload-img-preview',uploadNumberLimit()?'uoloadSty':'disUoloadSty',hideUploadEdit?'hide':'']"
              list-type="picture-card"
              accept="image/*"
              action=""
              :headers="{Authorization: cookie.get('bbcAuthorization_vs'),locale:lang}"
              :http-request="handleFileChange"
              :multiple="true"
              :auto-upload="false"
              :limit="options.limit"
              :before-upload="beforeUpload"
              :on-change="onUploadChange"
              :on-progress="onUploadProgress"
              :on-exceed="onUploadExceedTip"
              :before-remove="beforeRemove"
              :on-remove="onRemove"
            >
              <el-icon
                v-if="uploadNumberLimit()"
              >
                <Plus />
              </el-icon>
              <!--自定义缩略图-->
              <template #file="{ file }">
                <div>
                  <!--显示图片-->
                  <img
                    class="el-upload-list__item-thumbnail"
                    :src="file.url"
                    alt=""
                  >
                  <!--删除-->
                  <span class="el-upload-list__item-actions">
                    <span
                      class="el-upload-list__item-delete"
                      @click="handleRemove(file)"
                    >
                      <el-icon><Delete /></el-icon>
                    </span>
                  </span>
                </div>
              </template>
            </el-upload>
            <div class="upload-tip">
              {{ uploadTips() }}
            </div>
          </el-form-item>
        </el-form>
      </div>
    </div>
    <template #footer>
      <div>
        <div
          class="default-btn"
          @click="handleDialogClose"
        >
          {{ $t("shopFeature.edit.back") }}
        </div>
        <div
          class="primary-btn default-btn"
          @click="onUploadConfirm"
        >
          {{ $t("pictureManager.confirmUpload") }}
        </div>
      </div>
    </template>
    <group-add-or-update
      v-if="groupVisible"
      ref="groupAddOrUpdateRef"
      @get-group-data="getGroupList"
      @page-update-group="pageUpdateGroup"
    />
  </el-dialog>
</template>

<script setup>
import { Debounce } from '@/utils/debounce'
import ImageCompressor from 'compressorjs'
import { ElMessage, ElMessageBox } from 'element-plus'
import cookie from 'vue-cookies'

const emit = defineEmits(['getImgListData', 'getGroupData', 'handleDialogClose'])

const lang = reactive(localStorage.getItem('bbcLang') || 'zh_CN')
const options = reactive({
  multiple: true, // 是否支持选取多个图片
  limit: 20, // 最多可选择图片数量
  maxSize: 99999, // 最大尺寸（M）
  enableUpload: true, // 是否启用图片上传
  callback: null
})

const selectGroup = ref('')
const visible = ref(false)
const show = () => {
  selectGroup.value = ''
  getGroupList()
  visible.value = true
}

const hide = () => {
  visible.value = false
}

let fileIds = [] // 已选图片的fileId
/**
 * 批量移动分组
 */
const batchMove = () => {
  if (!fileIds.length) {
    ElMessage({
      message: $t('pictureManager.tips1'),
      type: 'error',
      duration: 1000
    })
  }
}

const pageUpdateGroup = () => {
  emit('getGroupData')
}

const groupList = ref([]) // 分组列表
/**
 * 获取分组列表
 */
const getGroupList = () => {
  http({
    url: http.adornUrl('/admin/fileGroup/list'),
    method: 'get',
    params: {
      type: 1 // 1、图片 2、视频 3、文件
    }
  }).then((res) => {
    groupList.value = res.data
  })
}

const groupVisible = ref(false)
const groupAddOrUpdateRef = ref(null)
const createGroup = () => {
  groupVisible.value = true
  nextTick(() => {
    groupAddOrUpdateRef.value?.show(1)
  })
}

const deleteGroup = (id) => {
  ElMessageBox.confirm($t('pictureManager.tips2'), $t('resource.tips'), {
    confirmButtonText: $t('resource.confirm'),
    cancelButtonText: $t('resource.cancel'),
    type: 'warning'
  }).then(() => {
    http({
      url: http.adornUrl('/admin/fileGroup'),
      method: 'delete',
      params: {
        attachFileGroupId: id
      }
    }).then(() => {
      getGroupList()
    })
  })
}

let uploadSubmitFlag = false
const uploadRef = ref(null)
const fileList = ref([])
/**
 * 提交上传图片
 */
const onUploadConfirm = Debounce(() => {
  uploadSubmitFlag = true
  const time = setTimeout(() => {
    uploadSubmitFlag = false
    clearTimeout(time)
  }, 1000)
  fileIds = []
  if (!fileList.value || !fileList.value.length) {
    return ElMessage.error($t('pictureManager.tips1'))
  }
  uploadRef.value?.submit()
}, 1000)

const onUploadProgress = () => {}

let uploadDisabled = false
const beforeRemove = () => {
  // 防止用户频繁点击导致删除过多
  return !uploadDisabled
}

let uploadFileNum = 0
const hideUploadEdit = ref(false) // 上传图片按钮显隐
const onRemove = () => {
  uploadFileNum = fileList.value.length
  const time = setTimeout(() => {
    hideUploadEdit.value = false
    clearTimeout(time)
  }, 1000)
  if (uploadSubmitFlag) {
    uploadDisabled = false
  } else {
    uploadDisabled = true
    const time1 = setTimeout(() => {
      uploadDisabled = false
      clearTimeout(time1)
    }, 1000)
  }
}

const onUploadChange = (filePar, fileListPar) => {
  uploadFileNum = fileListPar.length
  hideUploadEdit.value = fileListPar.length >= options.limit
}

let picNum = 0
let errShow = false
const errMsg = () => {
  if (errShow && uploadFileNum === picNum) {
    picNum = 0
    message($t('pictureManager.onlyPictures'), true)
    errShow = false
  }
}

/**
 * 上传图片前检查合法性
 * @param file
 * @returns {boolean}
 */
const beforeUpload = async (file) => {
  picNum++
  const typeArray = file.type.split('/')
  errMsg()
  if (typeArray[0] !== 'image') {
    errShow = true
    errMsg()
    return Promise().reject()
  }
  if (uploadFileNum === picNum) {
    picNum = 0
  }
  const isSize = file.size / 1024 < 512
  if (!isSize) {
    // 0.5m~5m，从0.8开始循环。5m~10m，从0.6开始循环。10m以上就直接0.4。
    // 最低使用0.4
    let quality
    if (file.size / 1024 / 1024 < 5) {
      quality = 0.8
    } else if (file.size / 1024 / 1024 < 10) {
      quality = 0.6
    } else {
      quality = 0.4
    }
    try {
      let resultBlob
      let index = true
      while (index) {
        resultBlob = await ImageCompressorFn(file, quality)
        if (resultBlob.size / 1024 < 512 || quality <= 0.4) {
          index = false
        } else {
          quality = (quality * 10 - 2) / 10
        }
      }
      return new File([resultBlob], file.name, {
        type: file.type
      })
    } catch (error) {
      return Promise().reject()
    }
  }
  return true
}

const ImageCompressorFn = (file, quality) => {
  return new Promise((resolve, reject) => {
    // eslint-disable-next-line no-new
    new ImageCompressor(file, {
      quality, // 压缩大小
      convertSize: 512000,
      success (result) {
        resolve(result)
      },
      error (err) {
        reject(err)
      }
    })
  })
}

const uploadNumberLimit = () => {
  if (!options.multiple) {
    return true
  }
  return options.limit - uploadFileNum
}

const uploadTypeTip = () => {
  return $t('pictureManager.onlySupported') + ' jpg/png/gif ' + $t('pictureManager.pic')
}

/*
const uploadSizeTip = () => {
  return $t('pictureManager.notExceed') + '2M'
}
*/

const uploadTips = () => {
  const tips = [uploadTypeTip()]

  if (!options.multiple) {
    return tips.join('，')
  }
  if (uploadFileNum > 0) {
    tips.push($t('pictureManager.soonUpload') + uploadFileNum + $t('pictureManager.unit'))
  }
  tips.push($t('pictureManager.remainder') + (options.limit - uploadFileNum) + $t('pictureManager.unit') + $t('pictureManager.upload'))

  return tips.join(',')
}

/**
 * 选择上传文件超过限制文件个数提示
 */
const onUploadExceedTip = () => {
  message($t('pictureManager.maxSelect') + uploadNumberLimit() + $t('pictureManager.unit') + $t('pictureManager.upload'))
}

const message = (msg, isInfo) => {
  let type = 'error'
  if (isInfo) {
    type = 'info'
  }
  ElMessage({
    message: msg,
    type,
    duration: 1500
  })
}
let resData = []
const handleFileChange = (e) => {
  const file = e.file
  http({
    url: http.adornUrl('/admin/file/getPreSignUrl'),
    method: 'get',
    params: http.adornParams({
      fileName: file.name,
      isImFile: false
    })
  }).then(async ({ data }) => {
    await uploadFile(data.preSignUrl, file).then(() => {
      resData.push({ fileId: data.fileId, attachFileGroupId: selectGroup.value, fileSize: file.size, type: 1 })
    }).catch((err) => {
      message($t('pictureManager.requestError'), true)
      throw err
    })
    if (resData.length === uploadFileNum) {
      http({
        url: http.adornUrl('/admin/file/uploadSuccess'),
        method: 'put',
        data: resData
      }).then(() => {
        hideUploadEdit.value = false
        resData = []
        if (!selectGroup.value) {
          visible.value = false
          emit('getImgListData')
          return ElMessage({
            type: 'success',
            message: $t('pictureManager.pic') + $t('resource.uploadSuccess')
          })
        }
        fileIds.value = []
        ElMessage({
          type: 'success',
          message: $t('pictureManager.pic') + $t('resource.uploadSuccess')
        })
        emit('getImgListData')
        visible.value = false
        uploadRef.value?.clearFiles()
      })
    }
  })
}
/**
 * 关闭回调
 */
const handleDialogClose = () => {
  emit('handleDialogClose')
  visible.value = false
  fileIds = []
}

/**
 * 手动移除图片
 * @param file 图片项
 */
const handleRemove = (file) => {
  // handleRemove为官方自带外部方法
  uploadRef.value?.handleRemove(file)
}

defineExpose({
  show,
  hide,
  deleteGroup,
  batchMove
})

</script>

<style lang="scss" scoped>
:deep(.elx-main) {
  .disUoloadSty &:deep(.el-upload--picture-card) {
    display: none; /* 上传按钮隐藏 */
  }

  &:deep(.el-upload-list--picture-card .el-upload-list__item-status-label) {
    top: -5px;
  }

  &:deep(.el-upload-list--picture-card .el-upload-list__item-status-label i) {
    vertical-align: top;
  }

  .select-group-box-item {
    margin-right: 10px;
  }

  div &:deep(.el-tabs__header) {
    display: none !important;
  }

  .upload-tip {
    width: 100%;
    font-size: 12px;
    color: #999999;
  }

  .hide &:deep(.el-upload--picture-card) {
    display: none;
  }

  .el-upload-list__item,.el-upload--picture-card {
    width: 78px !important;
    height: 78px !important;
    border-radius: 5px;
    position: relative;
  }

  .el-icon-plus {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
  }

}
</style>
